package com.ibm.parse.service;

import com.ibm.parse.dao.TextParseDAO;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class TextParseService {
	private static final Logger logger = LoggerFactory.getLogger(Object.class);
	private static String configFilePath = "regexConfig.properties";
	private static String comma = ",";
	private static String pipeline = "\\|";
	private TextParseDAO dao;
	private static List<String> regexList = new ArrayList();
	private static Map<String, Object> map = new HashMap();
	private static List<Map<String, Object>> identifierList = new ArrayList();

	private String bondPrefix = "[\\S]+(";

	private String bondSuffix = ")";

	private String periodPrefix = "[0-9]+(天|周|月|年|D|M|Y|d|m|y|个月)?(";
	private String periodMiddle = ")[0-9]+(天|周|月|年|D|M|Y|d|m|y|个月)|[0-9]+(天|周|个月|D|M|Y|d|m|y)|半年|跨月|隔夜|短期|足年|足月|[0-9]+(\\+[0-9]+)?(天|周|个月|D|M|Y|d|m|y)|(1|2|3|5|10)年|([一|二|两|三|四|五|六|七|八|九|十]|[0-9])+(天|个月|年|百天)(";
	private String periodSuffix = ")([一|二|两|三|四|五|六|七|八|九|十]|[0-9])+(天|个月|年|百天)|([一|二|两|三|四|五|六|七|八|九|十]|[0-9])+(天|个月|年|百天)";

	public TextParseDAO getDao() {
		return this.dao;
	}

	public void setDao(TextParseDAO dao) {
		this.dao = dao;
	}

	public List<String> getRegexList() {
		if (regexList.size() == 0) {
			setRegexList();
		}
		return regexList;
	}

	public Map<String, Object> getMap() {
		if (map.size() == 0) {
			setMap();
		}
		return map;
	}

	public void setMap() {
		map = findKeyword();
	}

	public List<Map<String, Object>> getIdentifierList() {
		if (identifierList.size() == 0) {
			setIdentifierList();
		}
		return identifierList;
	}

	public void setIdentifierList() {
		identifierList = findKindIdentifierList();
	}

	public void updateKeyword() {
		setMap();
		setRegexList();
	}

	public void updateKindIdentifier() {
		setIdentifierList();
	}

	private String match(String regex, String docText) {
		Pattern pattern = Pattern.compile(regex);

		Matcher matcher = pattern.matcher(docText);
		String text = "";
		while (matcher.find()) {
			text = text + matcher.group() + comma;
		}
		if (!text.equals("")) {
			text = text.substring(0, text.length() - 1);
		}
		return text;
	}

	private void setRegexList() {
		try {
			ClassLoader classLoader = Thread.currentThread()
					.getContextClassLoader();
			URL url = classLoader.getResource(configFilePath);
			InputStream input = url.openStream();
			Properties props = new Properties();
			props.load(input);
			regexList.clear();

			regexList.add(getMap().get("kind").toString());
			regexList.add(getMap().get("direction").toString());

			regexList.add(this.periodPrefix + getMap().get("period").toString()
							.concat(this.periodMiddle) + getMap().get("period").toString()
							.concat(this.periodSuffix));
			regexList.add(props.get("rate").toString() + "|"
					+ getMap().get("rate").toString());
			regexList.add(props.get("amount").toString());
			regexList.add(getMap().get("type").toString());
			regexList.add(getMap().get("acceptBank").toString());
			regexList.add(props.get("grade").toString());
			regexList.add(this.bondPrefix + getMap().get("bond").toString()
					+ this.bondSuffix);
			regexList.add(getMap().get("bondType").toString());
			regexList.add(getMap().get("issuerType").toString());
			regexList.add(getMap().get("issuerNature").toString());
			regexList.add(props.get("bondGrade").toString());
			regexList.add(getMap().get("billType").toString());
			regexList.add(getMap().get("riskLevel").toString());
			regexList.add(getMap().get("currency").toString());
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public String parse(String parseString) {
		String result = "";
		for (String regex : getRegexList()) {
			result = result + comma + match(regex, parseString);
		}
		result = result.substring(1);
		return result;
	}

	public List<Map<String, Object>> parseText2(String message) {
		List list = new ArrayList();

		List regexList = getRegexList();
		String kind = match((String) regexList.get(0), message);
		String direction = match((String) regexList.get(1), message);
		String period = match((String) regexList.get(2), message);
		String rate = match((String) regexList.get(3), message);
		String amount = match((String) regexList.get(4), message);
		String type = match((String) regexList.get(5), message);
		String acceptBank = match((String) regexList.get(6), message);
		String grade = getFirstElement(match((String) regexList.get(7), message));
		String bond = match((String) regexList.get(8), message);
		String bondType = match((String) regexList.get(9), message);
		String issuerType = match((String) regexList.get(10), message);
		String issuerNature = match((String) regexList.get(11), message);
		String bondGrade = getLastElement(match((String) regexList.get(12),
				message));
		String billType = match((String) regexList.get(13), message);
		String riskLevel = match((String) regexList.get(14), message);
		String currency = match((String) regexList.get(15), message);

		if ("".equals(kind)) {
			kind = findKind(message);
		}

		int rows = 1;
		String[] periods = new String[0];
		boolean multiPeriod = false;
		if ((!"".equals(period)) && (period.indexOf(comma) != -1)) {
			periods = period.split(comma);
			multiPeriod = true;
		}

		String[] rates = new String[0];
		boolean mutiRate = false;
		if ((!"".equals(rate)) && (rate.indexOf(comma) != -1)) {
			rates = rate.split(comma);
			mutiRate = true;
		}

		String[] amounts = new String[0];
		boolean mutiAmount = false;
		if ((!"".equals(amount)) && (amount.indexOf(comma) != -1)) {
			amounts = amount.split(comma);
			mutiAmount = true;
		}

		if (periods.length > rates.length)
			rows = periods.length;
		else if (rates.length != 0) {
			rows = rates.length;
		}

		for (int i = 0; i < rows; i++) {
			if (direction.indexOf(comma) != -1) {
				direction = direction.substring(0, direction.indexOf(comma));
			}

			if (("".equals(kind)) || ("".equals(direction))
					|| ("".equals(bondType))) {
				logger.info("Message:'".concat(message).concat(
						"', kind:'" + kind + "', direction:'" + direction
								+ "', bondType:'" + bondType + "'"));
			}
			Map map = new HashMap();
			map.put("kind", i > 0 ? "" : kind);

			map.put("direction", direction);
			if (multiPeriod)
				map.put("period", i < periods.length ? periods[i] : "");
			else {
				map.put("period", i > 0 ? "" : period);
			}
			if (mutiRate)
				map.put("rate", i < rates.length ? rates[i] : "");
			else {
				map.put("rate", i > 0 ? "" : rate);
			}

			if (mutiAmount)
				map.put("amount", i < amounts.length ? amounts[i] : "");
			else {
				map.put("amount", i > 0 ? "" : amount);
			}

			map.put("type", i > 0 ? "" : type);
			map.put("acceptBank", i > 0 ? "" : acceptBank);
			map.put("grade", i > 0 ? "" : grade);
			map.put("bond", i > 0 ? "" : bond);
			map.put("bondType", i > 0 ? "" : bondType);
			map.put("issuerType", i > 0 ? "" : issuerType);
			map.put("issuerNature", i > 0 ? "" : issuerNature);
			map.put("bondGrade", i > 0 ? "" : bondGrade);
			map.put("billType", i > 0 ? "" : billType);
			map.put("riskLevel", i > 0 ? "" : riskLevel);
			map.put("currency", i > 0 ? "" : currency);
			list.add(map);
		}

		return list;
	}

	private String getFirstElement(String str) {
		String result = "";
		if (str.indexOf(comma) != -1) {
			String[] results = str.split(comma);
			result = results[0];
		} else {
			result = str;
		}
		return result;
	}

	private String getLastElement(String str) {
		String result = "";
		if (str.indexOf(comma) != -1) {
			String[] results = str.split(comma);
			result = results[(results.length - 1)];
		}
		return result;
	}

	private String findKind(String message) {
		String kind = "";
		for (Map map : getIdentifierList()) {
			String newKind = map.get("kind").toString();
			String identifier = map.get("identifier").toString();
			String[] ids = identifier.split(pipeline);
			for (String id : ids) {
				if (message.contains(id)) {
					kind = newKind;
					return kind;
				}
			}
		}
		return kind;
	}

	public List<Map<String, Object>> parseText(String parseString) {
		List list = new ArrayList();
		Map map = new HashMap();

		List regexList = getRegexList();

		map.put("kind", match((String) regexList.get(0), parseString));
		map.put("direction", match((String) regexList.get(1), parseString));
		map.put("period", match((String) regexList.get(2), parseString));
		map.put("rate", match((String) regexList.get(3), parseString));
		map.put("amount", match((String) regexList.get(4), parseString));
		map.put("type", match((String) regexList.get(5), parseString));
		map.put("acceptBank", match((String) regexList.get(6), parseString));
		map.put("grade", match((String) regexList.get(7), parseString));
		map.put("bond", match((String) regexList.get(8), parseString));
		map.put("remark", match((String) regexList.get(9), parseString));
		map.put("issuerType", match((String) regexList.get(10), parseString));
		map.put("issuerNature", match((String) regexList.get(11), parseString));
		map.put("bondGrade", match((String) regexList.get(12), parseString));
		map.put("billType", match((String) regexList.get(13), parseString));
		map.put("riskLevel", match((String) regexList.get(14), parseString));
		map.put("currency", match((String) regexList.get(15), parseString));
		list.add(map);
		return list;
	}

	public List<Map<String, Object>> findKeywordList() {
		return this.dao.queryKeywordList();
	}

	public Map<String, Object> findKeyword() {
		return getDao().queryKeyword();
	}

	public List<Map<String, Object>> findKindIdentifierList() {
		return this.dao.queryKindIdentifierList();
	}

	public int update(String keywords) {
		return this.dao.update(keywords);
	}

	public static void main(String[] args) throws Exception {
		TextParseService test = new TextParseService();
	}
}